﻿#region Using
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
#endregion Using



namespace LloydGame
{
    class ScreenLobby : GameScreen
    {

        #region Fields
        protected GameScreenComponent m_menu_Back, m_menu_Ready, m_lobbylist_component, m_car_select_left, m_car_select_right;
        //protected NetworkSession m_network_session;
        protected MultiplayerType m_multiplayer_type;
        protected Texture2D m_car_bg;
        protected List<Texture2D> m_car_images;
        protected List<String> m_car_info;
        protected List<int> m_car_speed;
        protected int m_car_selected_id;
        protected int m_car_available; 
        #endregion Fields

        #region Constructor
        public ScreenLobby(Game p_game, GameScreen p_owner, MultiplayerType p_multiplayer_type)
            : base(p_game, "Game Lobby")
        {

            m_multiplayer_type = p_multiplayer_type;
            m_ownerscreen = p_owner;

            // Quick hack for fast multiplayer debugging
            if (m_ownerscreen.GetType().ToString() == "LloydGame.ScreenMultiplayer")
                ((ScreenMultiplayer)m_ownerscreen).lasterror = "";
            else
                ((Game1)m_game).networkSession.LocalGamers[0].IsReady = true;

            // Components
            m_menu_Ready = new GameScreenComponent("Ready", new Vector2(650, 140), new Vector2(100, 32), p_game);
            m_menu_Back = new GameScreenComponent("Back", new Vector2(650, 180), new Vector2(100, 32), p_game);
            m_car_select_left = new ScreenComponentLobbyGo(Texture2D.FromFile(p_game.GraphicsDevice, "Content\\hud_lobby_goleft.png"), new Vector2(120, 450), new Vector2(32, 32), p_game);
            m_car_select_right = new ScreenComponentLobbyGo(Texture2D.FromFile(p_game.GraphicsDevice, "Content\\hud_lobby_goright.png"), new Vector2(600, 450), new Vector2(32, 32), p_game);

            m_selectable_components.Add(m_menu_Ready);
            m_selectable_components.Add(m_menu_Back);
            m_selectable_components.Add(m_car_select_left);
            m_selectable_components.Add(m_car_select_right);

            m_lobbylist_component = new ScreenComponentLobbyList(new Vector2(75, 150), new Vector2(512, 300), p_game);

            // Load car bg texture
            m_car_bg = Texture2D.FromFile(p_game.GraphicsDevice, "Content\\hud_lobby_car_bg.png");

            // Load car images
            m_car_selected_id = 0;
            m_car_available = 2;
            m_car_images = new List<Texture2D>();
            m_car_images.Add(Texture2D.FromFile(p_game.GraphicsDevice, "Content\\hud_lobby_car0.png"));
            m_car_images.Add(Texture2D.FromFile(p_game.GraphicsDevice, "Content\\hud_lobby_car1.png"));

            m_car_info = new List<string>();
            m_car_info.Add("A typical small and fast RC car.\nFast acceleration, but watch out,\nin great speeds it might loose traction!");
            m_car_info.Add("A robust and nice looking RC car.\nUse the mass to your advantage,\nknock the competion of their wheels!");

            // Network
            //m_network_session = ((Game1)m_game).networkSession;
            ((Game1)m_game).networkSession.GamerJoined += ((Game1)m_game).NetworkGamerJoined;
            ((Game1)m_game).networkSession.GamerLeft += ((Game1)m_game).NetworkGamerLeft;
            ((Game1)m_game).networkSession.SessionEnded += ((Game1)m_game).NetworkSessionEnded;
            ((Game1)m_game).networkSession.SessionEnded += NetworkEnded;
            ((Game1)m_game).networkSession.GameStarted += ((Game1)m_game).NetworkGameStarted;
            ((Game1)m_game).networkSession.GameEnded += ((Game1)m_game).NetworkGameEnded;

            // Update gamerlist
            ((ScreenComponentLobbyList)m_lobbylist_component).gamers = ((Game1)m_game).networkSession.AllGamers;

            // Clear car type list
            /*m_car_types = new Dictionary<byte, int>(m_networkSession.AllGamers.Count);
            foreach (NetworkGamer t_gamer in m_networkSession.AllGamers)
            {
                m_car_types.Add(t_gamer.Id, 0);
            }*/


        }
        #endregion Constructor

        #region NetworkEnded
        public void NetworkEnded(object sender, NetworkSessionEndedEventArgs e)
        {
            // TODO: Display information on why we closed!
            this.Close();
        }
        #endregion NetworkEnded

        #region Update
        public override void Update(GameTime p_gametime)
        {
            base.Update(p_gametime);

            if (!m_rendersubscreen && m_ready)
            {
                // If mouse have moved, clear keyboard selection
                if (m_lastmouse.X != m_currentmouse.X || m_lastmouse.Y != m_currentmouse.Y)
                {
                    // Hit test all components (only menu items here anyway)
                    foreach (GameScreenComponent t_component in m_selectable_components)
                    {
                        t_component.HitTest(new Vector2(m_currentmouse.X, m_currentmouse.Y));
                    }
                }

                // Ready?
                if (m_menu_Ready.Active && m_activatetrigger)
                {
                    ((Game1)m_game).networkSession.LocalGamers[0].IsReady = !((Game1)m_game).networkSession.LocalGamers[0].IsReady;
                }

                // Back? (disconnect from server/lobby)
                if (m_menu_Back.Active && m_activatetrigger)
                {
                    Console.WriteLine("Disconnecting from network game!");
                    if (!((Game1)m_game).networkSession.IsDisposed)
                        ((Game1)m_game).networkSession.Dispose();
                    ((Game1)m_game).networkSession = null;

                    this.Close();
                }

                // Car select left
                if (m_car_select_left.Active && m_activatetrigger)
                {
                    m_car_selected_id -= 1;
                    if (m_car_selected_id < 0)
                        m_car_selected_id = m_car_available - 1;

                    // Send new car info
                    List<object> t_data_to_send = new List<object>();
                    t_data_to_send.Add(((Game1)m_game).networkSession.LocalGamers[0].Id); // Player id
                    t_data_to_send.Add(m_car_selected_id);
                    ((Game1)m_game).NetworkSendData(NetworkDataType.CarType, t_data_to_send, null);
                }

                // Car select right
                if (m_car_select_right.Active && m_activatetrigger)
                {
                    m_car_selected_id += 1;
                    if (m_car_selected_id > m_car_available - 1)
                        m_car_selected_id = 0;

                    // Send new car info
                    List<object> t_data_to_send = new List<object>();
                    t_data_to_send.Add(((Game1)m_game).networkSession.LocalGamers[0].Id); // Player id
                    t_data_to_send.Add(m_car_selected_id);
                    ((Game1)m_game).NetworkSendData(NetworkDataType.CarType, t_data_to_send, null);
                }

                // We have some things to do if we are host :)
                if (((Game1)m_game).networkSession != null && ((Game1)m_game).networkSession.IsHost)
                {
                    // Is everybody ready?
                    if (((Game1)m_game).networkSession.IsEveryoneReady)
                    {
                        ((Game1)m_game).networkSession.StartGame();
                    }
                }

            }

            // Store keyboard and mouse states
            StoreStates();
        }
        #endregion Update

        #region Draw
        public override void Draw()
        {
            if (!m_rendersubscreen)
            {
                m_spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.None, m_screenmatrix);

                // Draw game info
                m_spriteBatch.DrawString(m_normalfont, ((Game1)m_game).networkSession.Host.Gamertag + " game", new Vector2(80 + 1, 100 + 1), Color.Black);
                m_spriteBatch.DrawString(m_normalfont, ((Game1)m_game).networkSession.Host.Gamertag + " game", new Vector2(80, 100), Color.White);

                // Draw player count
                m_spriteBatch.DrawString(m_smallfont, ((Game1)m_game).networkSession.AllGamers.Count + " / " + ((Game1)m_game).networkMaxPlayers + " players", new Vector2(470 + 1, 128 + 1), Color.Black);
                m_spriteBatch.DrawString(m_smallfont, ((Game1)m_game).networkSession.AllGamers.Count + " / " + ((Game1)m_game).networkMaxPlayers + " players", new Vector2(470, 128), Color.White);

                // Draw menu components
                if (!((Game1)m_game).networkSession.LocalGamers[0].IsReady)
                    m_menu_Ready.Draw(m_spriteBatch, false);
                m_menu_Back.Draw(m_spriteBatch, false);

                // Draw lobby list
                m_lobbylist_component.Draw(m_spriteBatch, false);

                // Draw car bg
                m_spriteBatch.Draw(m_car_bg, new Vector2(120, 400), Color.White);

                // Draw car image and info
                m_spriteBatch.Draw(m_car_images[m_car_selected_id], new Vector2(170, 400), Color.White);
                m_spriteBatch.DrawString(m_tinyfont, m_car_info[m_car_selected_id], new Vector2(305, 405), Color.White);

                // Draw car select buttons
                m_car_select_left.Draw(m_spriteBatch, false);
                m_car_select_right.Draw(m_spriteBatch, false);

                m_spriteBatch.End();
            }
            else
            {
                m_subscreen.Draw();
            }

            base.Draw();
        }
        #endregion Draw

    }
}
